package com.example.fms.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.fms.dto.req.CategoriesReqDto;
import com.example.fms.dto.resp.*;
import com.example.fms.entity.Categories;
import com.example.fms.entity.Right;
import com.example.fms.mapper.CategoriesMapper;
import com.example.fms.mapper.RightMapper;
import com.example.fms.service.CategoriesService;
import com.example.fms.service.RightService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CategoriesServiceImpl extends ServiceImpl<CategoriesMapper, Categories> implements CategoriesService {
    @Resource
    CategoriesMapper categoriesMapper;
    @Override
    public List<CategoriesRespDto> getCategories(CategoriesReqDto reqDto) {
        List<Categories> categories = categoriesMapper.selectList(null);
        categories.forEach(s->{
            s.setCat_id(s.getCatId());
            s.setCat_pid(s.getCatPid());
            s.setCat_level(s.getCatLevel());
            s.setCat_deleted(s.getCatDeleted());
            s.setCat_name(s.getCatName());
        });
        Map<Long, List<Categories>> rightMap = categories.stream().collect(Collectors.groupingBy(Categories::getCat_pid));
        List<CategoriesRespDto> categoriesList = new ArrayList<>();
        for (Categories auth : categories) {
            if (auth.getCat_pid() == null || auth.getCat_pid() == 0) {
                CategoriesRespDto categoriesRespDto = new CategoriesRespDto();
                // 如果PID为0或null，则为一级菜单
                categoriesRespDto.setCat_pid(auth.getCat_pid());
                categoriesRespDto.setCat_id(auth.getCat_id());
                categoriesRespDto.setCat_name(auth.getCat_name());
                categoriesRespDto.setCat_level(auth.getCat_level());
                categoriesRespDto.setCat_deleted(auth.getCat_deleted());
                categoriesRespDto.setChildren(buildMenuTreeList(rightMap, auth.getCat_id()));
                categoriesList.add(categoriesRespDto);
            }
        }
        return categoriesList;
    }

    @Override
    public Boolean saveCategories(CategoriesReqDto req) {
        Categories categories = new Categories();
        categories.setCat_name(req.getCat_name());
        categories.setCat_pid(req.getCat_pid());
        categories.setCat_level(req.getCat_level());
        categories.setCat_deleted(0);
        categoriesMapper.insert(categories);
        return true;
    }

    @Override
    public CategoriesRespDto getCategoriesById(Long id) {
        CategoriesRespDto categoriesRespDto = new CategoriesRespDto();
        Categories categories = categoriesMapper.selectById(id);
        if (!Objects.isNull(categories)) {
            categoriesRespDto.setCat_pid(categories.getCatPid());
            categoriesRespDto.setCat_id(categories.getCatId());
            categoriesRespDto.setCat_name(categories.getCatName());
            categoriesRespDto.setCat_level(categories.getCatLevel());
            categoriesRespDto.setCat_deleted(categories.getCatDeleted());
        }
        return categoriesRespDto;
    }

    @Override
    public Boolean putCategoriesById(Long id, CategoriesReqDto req) {
        Categories categories = categoriesMapper.selectById(id);
        categories.setCat_name(req.getCat_name());
        categoriesMapper.updateById(categories);
        return true;
    }

    @Override
    public Boolean deleteCategoriesById(Long id) {
        categoriesMapper.deleteById(id);
        return true;
    }

    @Override
    public Page<CategoriesRespDto> getCategoriesPage(String type, Integer pagenum, Integer pagesize) {
        Page<CategoriesRespDto> page = new Page<>(pagenum,pagesize);
        List<CategoriesRespDto> goodsList = categoriesMapper.getGoodsList(page, type);
        if (CollectionUtil.isNotEmpty(goodsList)) {
            goodsList.forEach(s->{
                s.setCat_id(s.getCatId());
                s.setCat_name(s.getCatName());
                s.setCat_pid(s.getCatPid());
                s.setCat_level(s.getCatLevel());
                s.setCat_deleted(s.getCatDeleted());
            });
        }
        //获取goodsList中所有的catId
        List<Long> catIds = goodsList.stream().map(CategoriesRespDto::getCat_id).toList();
        LambdaQueryWrapper<Categories> qw = new LambdaQueryWrapper<>();
        qw.in(Categories::getCatPid, catIds);
        //二级
        List<Categories> categories = categoriesMapper.selectList(qw);
        if (CollectionUtil.isNotEmpty(categories)) {
            categories.forEach(s->{
                CategoriesRespDto categoriesRespDto = new CategoriesRespDto();
                categoriesRespDto.setCat_id(s.getCatId());
                categoriesRespDto.setCat_name(s.getCatName());
                categoriesRespDto.setCat_pid(s.getCatPid());
                categoriesRespDto.setCat_level(s.getCatLevel());
                categoriesRespDto.setCat_deleted(s.getCatDeleted());
                goodsList.add(categoriesRespDto);
            });
        }
        //获取categories的所有id
        //三级
        List<Long> catIdsTree = categories.stream().map(Categories::getCatId).toList();
        LambdaQueryWrapper<Categories> qwt = new LambdaQueryWrapper<>();
        qwt.in(Categories::getCatPid, catIdsTree);
        List<Categories> categorieList = categoriesMapper.selectList(qwt);
        if (CollectionUtil.isNotEmpty(categorieList)) {
            categorieList.forEach(s->{
                CategoriesRespDto categoriesRespDto = new CategoriesRespDto();
                categoriesRespDto.setCat_id(s.getCatId());
                categoriesRespDto.setCat_name(s.getCatName());
                categoriesRespDto.setCat_pid(s.getCatPid());
                categoriesRespDto.setCat_level(s.getCatLevel());
                categoriesRespDto.setCat_deleted(s.getCatDeleted());
                goodsList.add(categoriesRespDto);
            });
        }
        Map<Long, List<CategoriesRespDto>> rightMap = goodsList.stream().collect(Collectors.groupingBy(CategoriesRespDto::getCat_pid));
        List<CategoriesRespDto> categoriesList = new ArrayList<>();
        for (CategoriesRespDto auth : goodsList) {
            if (auth.getCat_pid() == null || auth.getCat_pid() == 0) {
                CategoriesRespDto categoriesRespDto = new CategoriesRespDto();
                // 如果PID为0或null，则为一级菜单
                categoriesRespDto.setCat_pid(auth.getCat_pid());
                categoriesRespDto.setCat_id(auth.getCat_id());
                categoriesRespDto.setCat_name(auth.getCat_name());
                categoriesRespDto.setCat_level(auth.getCat_level());
                categoriesRespDto.setCat_deleted(auth.getCat_deleted());
                categoriesRespDto.setChildren(buildMenuTree(rightMap, auth.getCat_id()));
                categoriesList.add(categoriesRespDto);
            }
        }
        page.setRecords(categoriesList);
        return page;
    }

    @Override
    public Boolean deleteById(Long id) {
        categoriesMapper.deleteById(id);
        return true;
    }

    private List<CategoriesRespTwoDto> buildMenuTreeList(Map<Long, List<Categories>> authMap, Long pid) {
        List<CategoriesRespTwoDto> children = new ArrayList<>();
        List<Categories> auths = authMap.getOrDefault(pid, new ArrayList<>());
        for (Categories auth : auths) {
            CategoriesRespTwoDto categoriesRespDto = new CategoriesRespTwoDto();
            categoriesRespDto.setCat_pid(auth.getCat_pid());
            categoriesRespDto.setCat_id(auth.getCat_id());
            categoriesRespDto.setCat_name(auth.getCat_name());
            categoriesRespDto.setCat_level(auth.getCat_level());
            categoriesRespDto.setCat_deleted(auth.getCat_deleted());
            categoriesRespDto.setChildren(buildMenuManTreeList(authMap, auth.getCat_id()));
            children.add(categoriesRespDto);
        }
        return children;
    }

    private List<CategoriesRespManDto> buildMenuManTreeList(Map<Long, List<Categories>> authMap, Long pid) {
        List<CategoriesRespManDto> children = new ArrayList<>();
        List<Categories> auths = authMap.getOrDefault(pid, new ArrayList<>());
        for (Categories auth : auths) {
            CategoriesRespManDto categoriesRespDto = new CategoriesRespManDto();
            categoriesRespDto.setCat_pid(auth.getCat_pid());
            categoriesRespDto.setCat_id(auth.getCat_id());
            categoriesRespDto.setCat_name(auth.getCat_name());
            categoriesRespDto.setCat_level(auth.getCat_level());
            categoriesRespDto.setCat_deleted(auth.getCat_deleted());
            children.add(categoriesRespDto);
        }
        return children;
    }


    private List<CategoriesRespTwoDto> buildMenuTree(Map<Long, List<CategoriesRespDto>> authMap, Long pid) {
        List<CategoriesRespTwoDto> children = new ArrayList<>();
        List<CategoriesRespDto> auths = authMap.getOrDefault(pid, new ArrayList<>());
        for (CategoriesRespDto auth : auths) {
            CategoriesRespTwoDto categoriesRespDto = new CategoriesRespTwoDto();
            categoriesRespDto.setCat_pid(auth.getCat_pid());
            categoriesRespDto.setCat_id(auth.getCat_id());
            categoriesRespDto.setCat_name(auth.getCat_name());
            categoriesRespDto.setCat_level(auth.getCat_level());
            categoriesRespDto.setCat_deleted(auth.getCat_deleted());
            categoriesRespDto.setChildren(buildMenuManTree(authMap, auth.getCat_id()));
            children.add(categoriesRespDto);
        }
        return children;
    }

    private List<CategoriesRespManDto> buildMenuManTree(Map<Long, List<CategoriesRespDto>> authMap, Long pid) {
        List<CategoriesRespManDto> children = new ArrayList<>();
        List<CategoriesRespDto> auths = authMap.getOrDefault(pid, new ArrayList<>());
        for (CategoriesRespDto auth : auths) {
            CategoriesRespManDto categoriesRespDto = new CategoriesRespManDto();
            categoriesRespDto.setCat_pid(auth.getCat_pid());
            categoriesRespDto.setCat_id(auth.getCat_id());
            categoriesRespDto.setCat_name(auth.getCat_name());
            categoriesRespDto.setCat_level(auth.getCat_level());
            categoriesRespDto.setCat_deleted(auth.getCat_deleted());
            children.add(categoriesRespDto);
        }
        return children;
    }

}
